////
/// Helpers
/// @group Helpers
/// @access private
////

// Logic
// ------------------------------

//  th-if()
/// Shorthand if else statement.
///
/// @since 0.0.14
/// @return {mixed} The return value of the condition.
///
/// @param {boolean} $condition - The condition to pass.
/// @param {mixed} $if-value - The return value if condition is true.
/// @param {mixed} $else-value - The return value if condition is false.
///
/// @example scss - If 2 plus 2 equals 8, return 10px, else return 20px.
///   th-if(2 + 2, 10px, 20px);
///   // 20px

@function th-if(
  $condition,
  $if-value,
  $else-value
){
  @if ($condition == true) {
    @return $if-value;
  } @else {
    @return $else-value;
  }
}

// Math
// ------------------------------

//  th-math-power()
/// Returns a powered number by exponent.
///
/// @since 0.0.11
/// @return {number} The powered number.
///
/// @param {number} $number - The base number.
/// @param {number} $exponent - The base number's exponent.
///
/// @example scss - Calculate 10 to the power of 3.
///   th-math-power(10, 3)
///   // 1000

@function th-math-power(
  $number,
  $exponent
){
  $_return: $number;
  @if $exponent > 1 {
    @for $i from 2 through $exponent {
      $_return: $_return * $number;
    }
  }
  @if $exponent < 1 {
    @for $i from 0 through -#{$exponent} {
      $_return: $_return / $number;
    }
  }
  @return $_return; 
}

//  th-math-round-to()
/// Returns a floated number rounded to a decimal point.
///
/// @since 0.0.11
/// @return {number} The rounded number.
///
/// @param {number} $number - The number to round from.
/// @param {number} $decimal - The decimal place to round to.
///
/// @example scss - Round 1.234 to 2 decimal places.
///   th-math-round-to(1.234, 2)
///   // 1.23

@function th-math-round-to(
  $number,
  $decimal
){
  $_return: $number;
  $_return: round( $number * th-math-power(10, $decimal) );
  $_return: $_return / th-math-power(10, $decimal);
  @return $_return;
}

// Maps
// ------------------------------

//  th-map-set()
/// Set a map key with a new value.
///
/// @since 0.0.15
/// @return {map} Map with new property
///
/// @param {map} $map - The map/haystack of values.
/// @param {string} $key - The key/needle used to find value.
/// @param {$value} $value - The new value of the map key.
///
/// @example scss - Set map key 'foo' to 'Hello World'
///   th-map-set(
///     (
///       foo: 'First',
///       bar: 'Second'
///     ),
///     $key: foo,
///     $value: 'Hello Word'
///   )
///   // (
///   //   foo: 'Hello World',
///   //   bar: 'Second'
///   // )

@function th-map-set(
  $map,
  $key,
  $value
){
  $_return: ();
  @each $item in $map {
    @if nth($item, 1) != $key {
      $_return: map-merge($_return, (nth($item, 1): nth($item, 2)));
    }
  }
  $_return: map-merge($_return, ($key: $value));
  @return $_return;
}

// Lists
// ------------------------------

//  th-list-has-index()
/// Check list for a index.
///
/// @since 0.0.11
/// @return {boolean} If list contains index.
///
/// @param {list} $list - List to search.
/// @param {number} $index - The list index to retrieve.
///
/// @example scss - Check list for 2n index.
///   th-list-has-index((a, b, c), 2);
///   // true

@function th-list-has-index(
  $list,
  $index
){
	$_return: false;
  @if list == type-of($list) and length($list) >= $index {
    $_return: true;
  }
  @return $_return;
}

//  th-list-get-index-deep()
/// Return the index of a value within multiple lists.
///
/// @since 0.0.11
/// @return {list} The index of the found value.
///
/// @param {list} $list - The list to search through.
/// @param {number | string} $find - The value to find.
///
/// @example scss - Get the index of 'f' in (a, b, (c, d, (e, f))).
///   th-list-get-index-deep( (a, b, (c, d, (e, f))), f )
///   // 3 3 2

@function th-list-get-index-deep(
  $list,
  $find,
  $indexes: ()
){
  $_return: $find;
  $index: 0;
  @if th-list-has($list, $find) {
    @if length($indexes) > 0 {
      $_return: append($indexes, index($list, $find));
    } @else {
      $_return: index($list, $find);
    }
  } @else {
    @each $value in $list {
      $index: $index + 1;
      @if type-of($value) == list {
        $_return: th-list-get-index-deep($value, $find, append($indexes, $index));
      }
    }
  }
  @return $_return;
}

//  th-list-has()
/// Check list for a value.
///
/// @since 0.0.11
/// @return {boolean} If list contains value.
///
/// @param {list} $list - List to search.
/// @param {number | string} $find - Value to find.
///
/// @example scss - Check list for 'b'.
///   th-list-has((a b c), b);
///   // true

@function th-list-has(
  $list,
  $find
){
  $_return: false;
  @each $value in $list {
    @if $find == $value {
      @return true;
    }
  }
  @return $_return;
}

//  th-list-get-nth-deep()
/// Return a nested value by index (recursive).
///
/// @since 0.0.14
/// @return {mixed} The nested list value.
///
/// @param {list} $list - List to search through.
/// @param {list} $indexes - List of indexes to recurse.
///
/// @example scss - Get (3 3 2)n in (a, b, (c, d, (e, f))).
///   th-list-get-nth-deep(3 3 2)
///   // f

@function th-list-get-nth-deep(
  $list,
  $indexes
){
  $_return: false;
  @if list == type-of($list) {
    $_return: $list;
    @for $i from 1 through length($indexes) {
      @if th-list-has-index($_return, nth($indexes, $i)) {
        $_return: nth($_return, nth($indexes, $i));
      } @else if $i == 1 {
        $_return: false;
      }
    }
  } @else if $indexes == 1 {
    $_return: $list;
  }
  @return $_return;
}

//  th-list-has-deep()
/// Check list for a value (recursive).
///
/// @since 0.0.10
/// @return {boolean} If list contains value.
///
/// @param {list} $list - List to search.
/// @param {number | string} $find - Value to find.
///
/// @example scss - Check for 'f' in (a b (c d (e f))).
///   th-list-has-deep((a b (c d (e f))), f)
///   // true

@function th-list-has-deep(
  $list,
  $find
){
  $_return: false;
  @each $value in $list {
    @if list == type-of($value) {
      $_return: th-list-has-deep($value, $find);
    } @else {
      @if $find == $value {
        @return true;
      }
    }
  }
  @return $_return;
}

//  th-list-flatten()
/// Turns multidimensional `$list` into a one-level list.
///
/// @since 0.0.15
/// @link https://github.com/at-import/SassyLists/blob/master/stylesheets/SassyLists/_flatten.scss
/// @return {list} Flattened one-level list.
///
/// @param {list} $list - Multidimensional list to flatten
///
/// @example scss - Flatten multidimensional list.
///   th-list-flatten(a, b, (c, d))
///   // (a, b, c, d)

@function th-list-flatten($list) {
  $result: ();
  @each $item in $list {
    @if length($item) > 1 {
      $flatten: th-list-flatten($item);
      @each $i in $flatten {
        $result: append($result, $i, list-separator($list));
      }
    }
    @else {
      $result: append($result, $item, list-separator($list));
    }
  }
  @return $result;
}

// Units
// ------------------------------

//  _th-unit-convert()
/// Coverts a number into another unit.
///
/// @since 0.0.14
/// @return {number} The converted number.
///
/// @param {string} $unit - (px|em|rem|rel|percent) A unit to convert the number to.
/// @param {number} $number - The number to convert.
/// @param {number} $base-font-size [$th-base-font-size] - Font size used for relative calculations.
///
/// @example scss - Convert 14px to em.
///   _th-unit-convert($unit: em, $number: 14px)
///   // 0.875em
/// @example scss - Convert 14px with base font size of 20px to em.
///   _th-unit-convert($unit: em, $number: 14px, $base-font-size: 20px)
///   // 0.700em

@function th-unit-convert(
  $unit,
  $number,
  $base-font-size: $th-base-font-size
){
  $function: th-unit-convert-#{$unit};
  @if function-exists($function) and unit($number) != $unit {
    @return call($function, $number, $base-font-size);
  } @else {
    @return $number;
  }
}

//  th-unit-strip()
/// Strips the unit from a number.
///
/// @since 0.0.11
/// @return {number} The stripped number.
///
/// @param {number} $number - Number to strip unit from.
///
/// @example scss - Strip px from 24px.
///   th-unit-strip(24px)
///   // 24

@function th-unit-strip(
  $number
){
  $_return: $number / ($number * 0 + 1);
  @return $_return;
}

//  th-unit-cast()
/// Creates a number with a unit.
///
/// @since 0.0.11
/// @return {number} The number with new unit.
///
/// @param {number} $number - The unitless number to create.
/// @param {string} $unit - The type of unit to create.
///
/// @example scss - Change 24 to 24px.
///   th-unit-cast(24, px);
///   // 24px

@function th-unit-cast(
  $number,
  $unit
){
  $_return: $number;
  $strings: px em rem;
  $units: 1px 1em 1rem;
  $index: index($strings, $unit);
  @if $index {
    $_return: $number * nth($units, $index);
  }
  @return $_return;
}

//  th-unit-convert-number()
/// Converts the unit of a number.
///
/// @since 0.0.11
/// @return {number} The converted number.
///
/// @param {number} $number - The numbered unit to convert.
/// @param {string} $unit - The unit to convert to.
///
/// @example scss - Convert unit of 24px to em.
///   th-unit-convert-number(24px, em)
///   // 24em

@function th-unit-convert-number(
  $number,
  $unit
){
  $_return: $number;
  $_return: th-unit-strip($number) * th-unit-cast(1, $unit);
  @if ($_return == th-unit-cast(0, $unit)) { 
    $_return: 0;
  }
  @return $_return;
}

//  th-unit-convert-absolute()
/// Converts a relative number to an absolute number.
///
/// @since 0.0.11
/// @return {number} The converted absolute number.
///
/// @param {number} $number - The number to convert.
/// @param {string} $unit - The type of absolute unit.
/// @param {number} $base-font-size [$th-base-font-size] - Font size used for relative calculations.
///
/// @example scss - Convert 2em to px.
///   th-unit-convert-absolute(2em, px)
///   // 32px
/// @example scss - Convert 2em to px with base font size of 10px.
///   th-unit-convert-absolute(2em, px, 10px);
///   // 20px

@function th-unit-convert-absolute(
  $number,
  $unit,
  $base-font-size: $th-base-font-size
){
  $_return: $number;
  $_return: th-unit-strip($number) * th-unit-strip($base-font-size);
  $_return: th-math-round-to($_return, 5);
  @if $unit {
    $_return: th-unit-convert-number($_return, $unit);
  }
  @return $_return;
}

//  th-unit-convert-relative()
/// Converts an absolute number to a relative number.
///
/// @since 0.0.11
/// @return {number} The converted relative number.
///
/// @param {number} $number - The number to convert.
/// @param {string} $unit - The type of relative unit.
/// @param {number} $base-font-size [$th-base-font-size] - Font size used for relative calculations.
///
/// @example scss - Convert 24px to em.
///   th-unit-convert-relative(24px, em)
///   // 1.5
/// @example scss - Convert 24px to em with a base font size of 32px.
///   th-unit-convert-relative(24px, em, 32px)
///   // 0.75em

@function th-unit-convert-relative(
  $number,
  $unit,
  $base-font-size: $th-base-font-size
){
  $_return: $number;
  $_return: th-unit-strip($number) / th-unit-strip($base-font-size);
  @if $unit {
    $_return: th-unit-convert-number($_return, $unit);
  }
  @return $_return;
}

//  th-unit-convert-em()
/// Converts an absolute number to an em number.
///
/// @since 0.0.11
/// @return {number} The converted number with em unit.
///
/// @param {number} $number - The number to convert.
/// @param {number} $base-font-size [$th-base-font-size] - Font size used for relative calculations.
///
/// @example scss - Convert 24px to em.
///   th-unit-convert-em(24px)
///   // 1.5em
/// @example scss - Convert 24px to em with a base font size of 32px.
///   th-unit-convert-em(24px, 32px)
///   // 0.75em

@function th-unit-convert-em(
  $number,
  $base-font-size: $th-base-font-size
){
  $_return: $number;
  $_return: th-math-round-to($_return, 5);
  $_return: th-unit-convert-relative($_return, em, $base-font-size);
  @return $_return;
}

//  th-unit-convert-rem()
/// Converts an absolute number to an rem number.
///
/// @since 0.0.11
/// @return {number} The converted number with rem unit.
///
/// @param {number} $number - The number to convert.
/// @param {number} $base-font-size [$th-rem-base] - Font size used for rem calculations.
///
/// @example scss - Convert 24px to rem.
///   th-unit-convert-rem(24px)
///   // 1.5rem
/// @example scss - Convert 24px to rem with a rem base of 32px.
///   th-unit-convert-rem(24px, 32px)
///   // 0.75rem

@function th-unit-convert-rem(
  $number,
  $base-font-size: $th-rem-base
){
  $_return: $number;
  $_return: th-math-round-to($_return, 5);
  $_return: th-unit-convert-relative($_return, rem, $th-rem-base);
  @return $_return;
}

//  th-unit-convert-rel
/// Converts an absolute number to a relative number.
///
/// @since 0.0.11
/// @return {number} The converted relative number.
///
/// @param {number} $number - The number to convert.
/// @param {number} $base-font-size [$th-base-font-size] - Font size used for relative calculations.
///
/// @example scss - Convert 24px to a relative number.
///   th-unit-convert-rel(24px)
///   // 1.5
/// @example scss - 24px to a relative number with a base font size of 32px.
///   th-unit-convert-rel(24px, 32px)
///   // 0.75

@function th-unit-convert-rel(
  $number,
  $base-font-size: $th-base-font-size
){
  $_return: $number;
  $_return: th-math-round-to($_return, 5);
  $_return: th-unit-convert-relative($_return, false, $base-font-size);
  @return $_return;
}

//  th-unit-convert-px()
/// Converts a relative number to a px number.
///
/// @since 0.0.11
/// @return {number} The converted absolute number.
///
/// @param {number} $number - The number to convert.
/// @param {number} $base-font-size [$th-base-font-size] - Font size used for relative calculations.
///
/// @example scss - Convert 2em to a px number.
///   th-unit-convert-absolute(2em)
///   // 32px
/// @example scss - Convert 2em to a px number with a base font size of 18px.
///   th-unit-convert-px(2em, 18px)
///   // 36px

@function th-unit-convert-px(
  $number,
  $base-font-size: $th-base-font-size
){
  $_return: $number;
  $_return: th-math-round-to($_return, 5);
  $_return: th-unit-convert-absolute($_return, px, $base-font-size);
  @return $_return;
}

//  th-unit-convert-percent
/// Converts an absolute number to a percentage.
///
/// @since 0.0.11
/// @return {number} The converted percentage number.
///
/// @param {number} $number - The number to convert.
/// @param {number} $base-font-size [$th-base-font-size] - Font size used for relative calculations.
///
/// @example scss - Convert 24px to a percentage.
///   th-unit-convert-rel(24px)
///   // 150%
/// @example scss - Convert 24px to a percentage with a base font size of 32px.
///   th-unit-convert-rel(24px, 32px)
///   // 75%

@function th-unit-convert-percent(
  $number,
  $base-font-size: $th-base-font-size
){
  $_return: $number;
  $_return: th-math-round-to($_return, 7);
  $_return: th-unit-convert-relative($number, false, $base-font-size);
  $_return: $_return * 100%;
  @return $_return;
}